`include "define.sv"
// 乘法器使能信号始终保持高电平
module pe_for_test (
    input clk,
    input reset,                  // 高电平复位
    input [1:0] data_type,        // 数据类型（INT4/INT8/FP16/FP32等）
    input mult_en,                // 乘法器使能
    input c_add_en,                // C矩阵加法使能信号
    input [`DATA_WIDTH-1:0] a_in, // 输入A（来自左侧PE）
    input [`DATA_WIDTH-1:0] b_in, // 输入B（来自上侧PE）
    input [`DATA_WIDTH-1:0] c_in,  // 输入C的数据
    output reg [`DATA_WIDTH-1:0] a_out, // 向右传递A（延迟一拍）
    output reg [`DATA_WIDTH-1:0] b_out, // 向下传递B（延迟一拍）
    output reg [`DATA_WIDTH-1:0] c_out,  // 累加结果输出
    output add_valid_o          // 流向下一级的valid
);

// 内部信号声明
wire [`DATA_WIDTH-1:0] mult_out; // 乘法器输出结果
wire mult_valid;                 // 乘法器输出有效信号
wire [`DATA_WIDTH-1:0] add_out; // 加法器输出结果

//reg c_added; // C矩阵添加标志

// 累加器寄存器（保存历史累加结果）
reg [`DATA_WIDTH-1:0] accumulator;  //历史累加结果
reg [`DATA_WIDTH-1:0] op2_in;       //来自乘法器结果或C矩阵寄存器的值
reg [`DATA_WIDTH-1:0] c_reg;   // C矩阵数值寄存器

// 数据传递逻辑
always @(posedge clk or posedge reset) begin
    if (reset) begin
        a_out <= {`DATA_WIDTH{1'b0}};
        b_out <= {`DATA_WIDTH{1'b0}};
    end else begin
        a_out <= a_in;  
        b_out <= b_in;  
    end
end

//  乘法器模块
Mult_top  mult_inst (
    .clk(clk),
    .sys_rst_n(!reset),
    .en(mult_en),               // 乘法器使能
    .data_type(data_type),
    .data_in(a_in),          // 直接使用当前输入（非寄存后的值）
    .weight_in(b_in),        // 直接使用当前输入（非寄存后的值）
    .float_o(mult_out),
    .mult_out_valid(mult_valid)
);

//  加法器模块（累加乘法结果）
Adder_top add_inst (
    .clk(clk),
    .sys_rst_n(!reset),
    .valid1(c_add_en),          // 属于累加的valid信号
    .valid2(mult_valid),    // 乘法结果有效时触发加法
    .data_type(data_type),
    .a_in(accumulator),     // 历史累加结果（操作数1）
    .b_in(mult_out),        // 乘法结果（操作数2）
    .float_o(add_out),
    .adder_valid(add_valid_o)
);

// 累加器更新逻辑
always @(posedge clk) begin
    if (c_add_en) begin

        accumulator <= c_in;

    end 
    else if (add_valid_o) begin

            accumulator <= add_out;
            c_out       <= add_out;

    end
end

endmodule

